﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections;
using System.ComponentModel;
using System.Reflection;

namespace Kokomo.Mirror.CliMetadata
{
	public abstract class MetadataTable : IListSource
	{
		protected MetadataTable(
			MetadataTableNumber number,
			MetadataContainer container = null
			)
		{
			this.Number = number;
			this.Container = container;
		}

		public MetadataContainer Container { get; private set; }

		public override string ToString()
		{
			return string.Format("{0}, RowCount={1}", this.Number, this.RowCount);
		}

		public MetadataTableNumber Number { get; private set; }

		public abstract Type RowType { get; }
		public abstract int RowCount { get; }
		public abstract void Populate(int rows);

		public abstract IMetadataRow GetItem(int index);

		public bool ContainsListCollection
		{
			get { throw new NotImplementedException(); }
		}

		public abstract IList GetList();
	}
	public class MetadataTable<TRow> :
		MetadataTable,
		IEnumerable<TRow>
		//IBindingList,
		//ITypedList
		where TRow : IMetadataRow, new()
	{
		public List<TRow> Rows { get; private set; }

		public MetadataTable(
			MetadataTableNumber number,
			MetadataContainer container = null
			)
			: base(number, container)
		{
			this.Rows = new List<TRow>();
		}

		public override Type RowType
		{
			get { return typeof(TRow); }
		}

		public override int RowCount
		{
			get { return this.Rows.Count; }
		}

		public virtual TRow this[int index]
		{
			get { return this.Rows[index]; }
		}
		public override IMetadataRow GetItem(int index)
		{
			return this[index];
		}

		public override void Populate(int rows)
		{
			while (rows-- > 0)
			{
				this.Rows.Add(new TRow());
			}
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return this.Rows.GetEnumerator();
		}
		IEnumerator<TRow> IEnumerable<TRow>.GetEnumerator()
		{
			return this.Rows.GetEnumerator();
		}

		public override IList GetList()
		{
			if (this.Container != null)
				return new MetadataTypedList(
					typeof(TRow),
					this.Rows.OfType<IMetadataRow>().ToArray(),
					this.Container
					);
			else
				return new TypedBindingList<TRow>(this.Rows, UiString.FromString(this.Number.ToString()));
		}

	}
}
